#ifndef SHIJU_EUTRAN_TCP_RECEIVER_H_INCLUDE
#define SHIJU_EUTRAN_TCP_RECEIVER_H_INCLUDE

#include <list>
#include <map>
#include <set>
#include <string>
#include <stdint.h>
#include <unistd.h>
#include <sys/time.h>
#include <stdlib.h>
#include <arpa/inet.h>

#define EutranTcpReceiverPtr (EutranTcpReceiver::instance())

class EutranTcpReceiver
{
public:
    static EutranTcpReceiver* instance();

    bool initialize();
    int32_t getServerFd();
    int32_t getMaxFd();
    int32_t getFd(in_addr_t addr);
    fd_set getReadFdSet();
    fd_set getWriteFdSet();
    fd_set getExceptionFdSet();

    void handleReadEvents(fd_set* readFds);
    void handleWriteEvents(fd_set* readFds);
    void handleExcepEvents(fd_set* excepFds);
    void shutdown(in_addr_t bbuAddr);

    bool sendMessage(in_addr_t bbuAddr, uint8_t* msgBuf, uint32_t msgSize);
private:
    EutranTcpReceiver();
    EutranTcpReceiver(const EutranTcpReceiver&);
    EutranTcpReceiver& operator=(const EutranTcpReceiver&);

    bool initServerFd();
    void handleReadEvent(int32_t fd);
    void shutdown(int32_t fd);
    bool sendBuffer(int32_t fd);

    int32_t maxFd_;
    int32_t serverFd_;
    std::map<in_addr_t, int32_t> clientFds_;
    std::map<int32_t, std::string> recvBuffer_;
    std::map<int32_t, std::string> sendBuffer_;
    std::map<int32_t, in_addr_t> clientAddr_;
    std::set<int32_t> writableFds_;
    fd_set readFdSet_;
    fd_set writeFdSet_;
    fd_set exceptionFdSet_;
};

#endif
